﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Security.Cryptography;

namespace MacroApp
{
    public static class Functions
    {
        /// <summary>
        /// add string into richtextbox
        /// </summary>
        /// <param name="strTextToAdd"></param>
        /// <param name="rtxHelp"></param>
        public static void AddColouredText(string strTextToAdd, RichTextBox rtxHelp)
        {
            //Use the RichTextBox to create the initial RTF code
            rtxHelp.Clear();
            rtxHelp.AppendText(strTextToAdd);
            string strRTF = rtxHelp.Rtf;
            rtxHelp.Clear();

            /* 
             * ADD COLOUR TABLE TO THE HEADER FIRST 
             * */

            // Search for colour table info, if it exists (which it shouldn't)
            // remove it and replace with our one
            int iCTableStart = strRTF.IndexOf("colortbl;");

            if (iCTableStart != -1) //then colortbl exists
            {
                //find end of colortbl tab by searching
                //forward from the colortbl tab itself
                int iCTableEnd = strRTF.IndexOf('}', iCTableStart);
                strRTF = strRTF.Remove(iCTableStart, iCTableEnd - iCTableStart);

                //now insert new colour table at index of old colortbl tag
                strRTF = strRTF.Insert(iCTableStart,
                    // CHANGE THIS STRING TO ALTER COLOUR TABLE
                    "colortbl ;\\red255\\green0\\blue0;\\red0\\green128\\blue0;\\red0\\green0\\blue255;}");
            }

            //colour table doesn't exist yet, so let's make one
            else
            {
                // find index of start of header
                int iRTFLoc = strRTF.IndexOf("\\rtf");
                // get index of where we'll insert the colour table
                // try finding opening bracket of first property of header first                
                int iInsertLoc = strRTF.IndexOf('{', iRTFLoc);

                // if there is no property, we'll insert colour table
                // just before the end bracket of the header
                if (iInsertLoc == -1) iInsertLoc = strRTF.IndexOf('}', iRTFLoc) - 1;

                // insert the colour table at our chosen location                
                strRTF = strRTF.Insert(iInsertLoc,
                    // CHANGE THIS STRING TO ALTER COLOUR TABLE
                    "{\\colortbl ;\\red128\\green0\\blue0;\\red0\\green128\\blue0;\\red0\\green0\\blue255;}");
            }

            /*
             * NOW PARSE THROUGH RTF DATA, ADDING RTF COLOUR TAGS WHERE WE WANT THEM
             * In our colour table we defined:
             * cf1 = red  
             * cf2 = green
             * cf3 = blue             
             * */

            for (int i = 0; i < strRTF.Length; i++)
            {
                if (strRTF[i] == '<')
                {
                    //add RTF tags after symbol 
                    //Check for comments tags 
                    if (strRTF[i + 1] == '!')
                        strRTF = strRTF.Insert(i + 4, "\\cf2 ");
                    else
                        strRTF = strRTF.Insert(i + 1, "\\cf1 ");
                    //add RTF before symbol
                    strRTF = strRTF.Insert(i, "\\cf3 ");

                    //skip forward past the characters we've just added
                    //to avoid getting trapped in the loop
                    i += 6;
                }
                else if (strRTF[i] == '>')
                {
                    //add RTF tags after character
                    strRTF = strRTF.Insert(i + 1, "\\cf0 ");
                    //Check for comments tags
                    if (strRTF[i - 1] == '-')
                    {
                        strRTF = strRTF.Insert(i - 2, "\\cf3 ");
                        //skip forward past the 6 characters we've just added
                        i += 8;
                    }
                    else
                    {
                        strRTF = strRTF.Insert(i, "\\cf3 ");
                        //skip forward past the 6 characters we've just added
                        i += 6;
                    }
                }
            }
            rtxHelp.Rtf = strRTF;
        }
        /// <summary>
        /// Encrypt a string using dual encryption method. Return a encrypted cipher Text
        /// </summary>
        /// <param name="toEncrypt">string to be encrypted</param>
        /// <param name="useHashing">use hashing? send to for extra secirity</param>
        /// <returns></returns>
        public static string Encrypt(string toEncrypt, bool useHashing)
        {
            byte[] keyArray;
            byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);

            // Get the key from config file
            string key = @"SecurityKey";
            //System.Windows.Forms.MessageBox.Show(key);
            if (useHashing)
            {
                using (MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider())
                {
                    keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
                }
            }
            else
                keyArray = UTF8Encoding.UTF8.GetBytes(key);

            byte[] resultArray = null;
            using (TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider())
            {
                tdes.Key = keyArray;
                tdes.Mode = CipherMode.ECB;
                tdes.Padding = PaddingMode.PKCS7;
                using (ICryptoTransform cTransform = tdes.CreateEncryptor())
                {
                    resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
                }
            }
            return Convert.ToBase64String(resultArray, 0, resultArray.Length);
        }
        /// <summary>
        /// DeCrypt a string using dual encryption method. Return a DeCrypted clear string
        /// </summary>
        /// <param name="cipherString">encrypted string</param>
        /// <param name="useHashing">Did you use hashing to encrypt this data? pass true is yes</param>
        /// <returns></returns>
        public static string Decrypt(string cipherString, bool useHashing)
        {
            byte[] keyArray;
            byte[] toEncryptArray = Convert.FromBase64String(cipherString);

            //Get your key from config file to open the lock!
            string key = @"SecurityKey";

            if (useHashing)
            {
                using (MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider())
                {
                    keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
                }
            }
            else
                keyArray = UTF8Encoding.UTF8.GetBytes(key);


            byte[] resultArray = null;
            using (TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider())
            {
                tdes.Key = keyArray;
                tdes.Mode = CipherMode.ECB;
                tdes.Padding = PaddingMode.PKCS7;
                using (ICryptoTransform cTransform = tdes.CreateDecryptor())
                {
                    resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
                }
            }
            return UTF8Encoding.UTF8.GetString(resultArray);
        }
        /// <summary>
        /// Kiem tra va tra ve chuoi string
        /// </summary>
        /// <param name="obj"></param>
        /// <returns>Neu khac rong tra ve chuoi, = rong ra ve ""</returns>
        public static string ObjectToSring(object obj)
        {
            string returnvalue = "";
            if (!Functions.IsNull(obj))
            {
                returnvalue = obj.ToString();
            }
            return returnvalue;
        }
        /// <summary>
        /// bo tat ca ky tu dac biet, thay bang "-"
        /// </summary>
        /// <param name="s"></param>
        /// <returns>string</returns>
        public static string RemoveSpecial(ref string s)
        {
            string regExp = @"\W";
            return s = Regex.Replace(s, regExp, "-");
        }
        /// <summary>
        /// tao folder chua file Save Attach. truyen vao thu muc goc va thu muc con la dia chi email.
        /// </summary>
        /// <param name="folderSub"></param>
        /// <param name="folderRoot"></param>
        /// <returns>Kiem tra xem neu thu muc con co trong thu muc goc hay chua, neu chua co tao va tra ve duong dan den thu muc con!</returns>
        public static string CreatePath(ref string folderSub, string folderRoot)
        {
            try
            {

                if (!Directory.Exists(folderRoot))
                {
                    Directory.CreateDirectory(folderRoot);
                }
                folderSub = string.Format(@"{0}\{1}\{2}", folderRoot, DateTime.Now.ToString("yyyy-MM-dd"), folderSub);
                if (!Directory.Exists(folderSub))
                {
                    Directory.CreateDirectory(folderSub);
                }
                return folderSub;
            }
            catch
            {
                return "";
            }
        }
        /// <summary>
        /// Tra ve true neu chuoi null or chieu dai = 0
        /// </summary>
        /// <param name="s"></param>
        /// <returns>return true or false</returns>
        public static bool IsBlank(string s)
        {
            return string.IsNullOrEmpty(s);
        }
        /// <summary>
        /// Kiem tra doi tuong co null hay khong?
        /// </summary>
        /// <param name="argObject"></param>
        /// <returns>return true or false</returns>
        public static bool IsNull(object argObject)
        {
            bool returnvalue = false;
            if (argObject == null)
            {
                returnvalue = true;
            }
            return returnvalue;
        }
        /// <summary>
        /// if is numeric return numeric else 
        /// </summary>
        /// <param name="val"></param>
        /// <param name="NumberStyle"></param>
        /// <returns></returns>
        public static bool isInt(string val)
        {
            int result;
            return int.TryParse(val, System.Globalization.NumberStyles.Integer,
                System.Globalization.CultureInfo.CurrentCulture, out result);
        }
        /// <summary>
        /// if a > b return true else false
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static bool Compare(int a, int b)
        {
            bool returnvalue = false;
            int x = a - b;
            if (x > 0)
            {
                returnvalue = true;
            }
            return returnvalue;
        }
        public static bool IsValidEmail(string emailAddr)
        {
            bool valid = false;
            string pattern = string.Format(@"^[a-zA-Z][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$");
            Match emailAddressMatch = Regex.Match(emailAddr, pattern);
            if (emailAddressMatch.Success)
            {
                valid = true;
            }
            return valid;
        }
    }
}
